package cn.edu.xmu.oomall.liquidation.model.bo.liquid.calc;

import cn.edu.xmu.oomall.liquidation.model.bo.Liquidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class CalcTotal {
    private static final Logger logger = LoggerFactory.getLogger(CalcTotal.class);

    private HashMap<String, Long> calcTotal = new HashMap<>();

    public CalcTotal() {

    }

    public CalcTotal(Collection<String> keys) {
        for(String key : keys) {
            calcTotal.put(key, 0L);
        }
    }

    public CalcTotal(String... keys) {
        for(String key : keys) {
            calcTotal.put(key, 0L);
        }
    }

    public Long get(String key) {
        return calcTotal.get(key);
    }

    public void add(String key, Long value) {
        Long originValue = Optional.ofNullable(calcTotal.get(key)).orElse(0L);
        calcTotal.put(key, originValue + value);
    }

    public void add(Map<String, Long> calcMap) {
        for(Map.Entry<String, Long> calcItem : calcMap.entrySet()) {
            if (calcTotal.containsKey(calcItem.getKey())) {
                this.add(calcItem.getKey(), calcItem.getValue());
            }
        }
    }

    public void add(CalcTotal otherCalcTotal) {
        add(otherCalcTotal.calcTotal);
    }

    public void changeLiquid(Liquidation liquidation) {
        Class<? extends Liquidation> aClass = liquidation.getClass();
        for(Map.Entry<String, Long> calcItem : calcTotal.entrySet()) {
            try {
                Field declaredField = aClass.getDeclaredField(calcItem.getKey());
                declaredField.setAccessible(true);
                Long originValue = Optional.ofNullable((Long)declaredField.get(liquidation)).orElse(0L);
                declaredField.set(liquidation, originValue + calcItem.getValue());
            } catch (NoSuchFieldException | IllegalAccessException e) {
                logger.error(e.getMessage());
            }
        }
    }
}
